package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.cache.key.RedisKey;
import cn.wolfcode.luowowo.cache.service.IAnswerCacheService;
import cn.wolfcode.luowowo.cache.vo.AnswerStats;
import cn.wolfcode.luowowo.cache.vo.UserAnswer;
import cn.wolfcode.luowowo.common.util.Consts;
import cn.wolfcode.luowowo.common.util.DateUtil;
import cn.wolfcode.luowowo.member.domain.UserInfo;
import cn.wolfcode.luowowo.member.service.IUserInfoService;
import com.alibaba.fastjson.JSON;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class AnswerCacheServiceImpl implements IAnswerCacheService {
    @Autowired
    private StringRedisTemplate template;
    @Reference
    private IUserInfoService userInfoService;


    public void setAnswerStats(AnswerStats vo) {
        String cacheKey = RedisKey.ANSWER_STATS.getCacheKey(vo.getAId());
        template.opsForValue().set(cacheKey, JSON.toJSONString(vo));
    }

    public AnswerStats getAnswerStats(Object aId) {
        String cacheKey = RedisKey.ANSWER_STATS.getCacheKey(aId);
        String json = template.opsForValue().get(cacheKey);
        return JSON.parseObject(json, AnswerStats.class);
    }

    public List<AnswerStats> listAnswerByQid(String qId) {
        ValueOperations<String, String> op = template.opsForValue();
        List vos = new ArrayList();
        //拿出所带ANSWER_STATS *的key
        String cacheKey = RedisKey.ANSWER_STATS.getCacheKey("*");
        Set<String> keys = template.keys(cacheKey);
        for (String key : keys) {
            String json = op.get(key);
            vos.add(JSON.parseObject(json, AnswerStats.class));
        }
        return vos;
    }

    public List<UserAnswer> sortCondition(Integer type, Integer rank, String cacheKey) {
        List<UserAnswer> list = new ArrayList();
        Set<String> keys = template.keys(cacheKey);
        for (String key : keys) {
            //这个方法会返回 value和分数
            Set<ZSetOperations.TypedTuple<String>> typedTuples = template.opsForZSet().reverseRangeWithScores(key, 0, 10);
            for (ZSetOperations.TypedTuple<String> typedTuple : typedTuples) {
                Long userId = Long.valueOf(typedTuple.getValue());
                Double score = typedTuple.getScore();
                UserInfo user = userInfoService.getById(userId);
                UserAnswer vo = new UserAnswer();
                vo.setUsername(user.getNickname());
                vo.setLevel(user.getLevel());
                vo.setHeadUrl(user.getHeadImgUrl());
                vo.setUserId(user.getId());
                vo.setReplyNums(score.intValue());
                list.add(vo);
            };
        }
        return list;
    }


    public void setuserThumbupDay(String prefix, Long userId, int num,int type) {
        ZSetOperations<String, String> op = template.opsForZSet();
        Date now = new Date();
        if (type==0) {
            String cacheKey = RedisKey.THUMBUP_UP_SORT_DAY.getPrefix();
            Date endDate = DateUtil.getEndDate(now);
            op.incrementScore(cacheKey, userId.toString(), num);
            template.expire(cacheKey, DateUtil.getDateBetween(now, endDate), TimeUnit.MILLISECONDS);
        }else if(type==1){
            String cacheWeek = RedisKey.THUMBUP_UP_SORT_WEEK.getPrefix();
            //本周的结束时间
            Date week = DateUtil.getBeginDayOfWeek();
            op.incrementScore(cacheWeek, userId.toString(), num);
            template.expire(cacheWeek, DateUtil.getDateBetween(now, week), TimeUnit.MILLISECONDS);
        }else if(type==2){
            String cacheMonth = RedisKey.THUMBUP_UP_SORT_MONTH.getPrefix();
            //本月的结束时间
            Date month = DateUtil.getEndDateOfMonth();
            op.incrementScore(cacheMonth, userId.toString(), num);
            template.expire(cacheMonth, DateUtil.getDateBetween(now, month), TimeUnit.MILLISECONDS);
        }
    }

    public void setuserGoldDay(String prefix, Long userId, int num,int type) {
        Date now = new Date();
        ZSetOperations<String, String> op = template.opsForZSet();
        if (type==0) {
            String cacheKey = RedisKey.GOLD_UP_SORT_DAY.getPrefix();
            Date endDate = DateUtil.getEndDate(now);
            op.incrementScore(cacheKey, userId.toString(), num);
            template.expire(cacheKey, DateUtil.getDateBetween(now, endDate), TimeUnit.MILLISECONDS);

        }else if(type==1){
            String cacheWeek = RedisKey.GOLD_UP_SORT_WEEK.getPrefix();
            //本周的结束时间
            Date week = DateUtil.getBeginDayOfWeek();
            op.incrementScore(cacheWeek, userId.toString(), num);
            template.expire(cacheWeek, DateUtil.getDateBetween(now, week), TimeUnit.MILLISECONDS);
        }else if(type==2){
            String cacheMonth = RedisKey.GOLD_UP_SORT_MONTH.getPrefix();
            op.incrementScore(cacheMonth, userId.toString(), num);
            //本月的结束时间
            Date month = DateUtil.getEndDateOfMonth();
            template.expire(cacheMonth, DateUtil.getDateBetween(now, month), TimeUnit.MILLISECONDS);
        }
    }

    public boolean exist(String id) {
        String cacheKey = RedisKey.ANSWER_STATS.getCacheKey(id);
        return template.hasKey(cacheKey);
    }

    public void setUserAnswerDay(String prefix, Long userId, int num,int type) {
        ZSetOperations<String, String> op = template.opsForZSet();
        Date now = new Date();
        if(type==0){
            String cacheKey = RedisKey.ANSWER_UP_SORT_DAY.getPrefix();
            op.incrementScore(cacheKey, userId.toString(), num);
            Date endDate = DateUtil.getEndDate(now);
            template.expire(cacheKey, DateUtil.getDateBetween(now, endDate), TimeUnit.MILLISECONDS);
        }else if(type==1){
            String cacheWeek = RedisKey.ANSWER_UP_SORT_WEEK.getPrefix();
            //本周的结束时间
            Date week = DateUtil.getBeginDayOfWeek();
            op.incrementScore(cacheWeek, userId.toString(), num);
            template.expire(cacheWeek, DateUtil.getDateBetween(now, week), TimeUnit.MILLISECONDS);
        }else if(type==2){
            String cacheMonth = RedisKey.ANSWER_UP_SORT_MONTH.getPrefix();
            //本月的结束时间
            Date month = DateUtil.getEndDateOfMonth();
            op.incrementScore(cacheMonth, userId.toString(), num);
            template.expire(cacheMonth, DateUtil.getDateBetween(now, month), TimeUnit.MILLISECONDS);
        }
    }

    public List<UserAnswer> getUserAnswer(Integer type, Integer rank, String cacheKey) {
        if (type == 0) {
            switch (rank) {
                case GOLD:
                    cacheKey = RedisKey.GOLD_UP_SORT_DAY.getPrefix();
                    break;
                case ANSWER:
                    cacheKey = RedisKey.ANSWER_UP_SORT_DAY.getPrefix();
                    break;
                case THUMBUP:
                    cacheKey = RedisKey.THUMBUP_UP_SORT_DAY.getPrefix();
                    break;
            }
        } else if (type == 1) {
            switch (rank) {
                case GOLD:
                    cacheKey = RedisKey.GOLD_UP_SORT_WEEK.getPrefix();
                    break;
                case ANSWER:
                    cacheKey = RedisKey.ANSWER_UP_SORT_WEEK.getPrefix();
                    break;
                case THUMBUP:
                    cacheKey = RedisKey.THUMBUP_UP_SORT_WEEK.getPrefix();
                    break;
            }
        } else if (type == 2) {
            switch (rank) {
                case GOLD:
                    cacheKey = RedisKey.GOLD_UP_SORT_MONTH.getPrefix();
                    break;
                case ANSWER:
                    cacheKey = RedisKey.ANSWER_UP_SORT_MONTH.getPrefix();
                    break;
                case THUMBUP:
                    cacheKey = RedisKey.THUMBUP_UP_SORT_MONTH.getPrefix();
                    break;
            }
        }
        return sortCondition(type, rank, cacheKey);
    }


    public boolean answerThumbup(Long userId, String aId) {
        boolean flag = false;
        //判断当前攻略在缓存在是否有key
        String key = userId.toString() + ":" + aId;
        String cacheKey = RedisKey.ANSWER_STATS_THUMBUP.getCacheKey(key);
        if (!template.hasKey(cacheKey)) {  //如果没有这个key说明没有顶
            Date now = new Date();
            Date endDate = DateUtil.getEndDate(now);
            //往redis中存入key
            template.opsForValue().set(cacheKey, "", DateUtil.getDateBetween(now, endDate), TimeUnit.MILLISECONDS);
            //回答收藏数加1
            incrNum(aId, 1, STRATEGY_STATS_THUMBUP);
            flag = true;
        }
        return flag;
    }

    public boolean hasKey(String id) {
        String cacheKey = RedisKey.ANSWER_STATS.getCacheKey(id);
        return template.hasKey(cacheKey);
    }


    private void incrNum(String aId, int num, int type) {
        AnswerStats vo = getAnswerStats(aId);
        switch (type) {
            case STRATEGY_STATS_THUMBUP:
                vo.setThumbsupnum(vo.getThumbsupnum() + num);
                break;
        }
        setAnswerStats(vo);
    }


}
